﻿using PLCWpfTest.Common.Extensions;
using PLCWpfTest.Views;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using YWM;
using YWM.Common.Exceptions;
using YWM.Exceptions;

namespace PLCWpfTest
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private readonly IExceptionHandler _exceptionHandler;

        public App()
        {
            YApp.CreateBuilder().SetSerilogConfigAction().Build<PLCModule>(true);
            _exceptionHandler = YApp.Resolve<IExceptionHandler>();
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            DispatcherUnhandledException += App_DispatcherUnhandledException;
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
        }

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            LoginWindow loginWindow = YApp.Resolve<LoginWindow>();
            if (loginWindow.ShowDialog() == true)
            {
                MainWindow mainWindow = YApp.Resolve<MainWindow>();
                mainWindow.ShowDialog();
            }
            Current.Shutdown();
        }

        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Exception exception = (Exception)e.ExceptionObject;
            _exceptionHandler.OnHandleException(exception, "子线程");
            Dispatcher.Invoke(() => this.ShowError(exception.Message));
        }

        private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            _exceptionHandler.OnHandleException(e.Exception, "UI线程", HandleFriendlyException);
            e.Handled = true;
        }

        private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            Exception exception = e.Exception.InnerException ?? e.Exception;
            _exceptionHandler.OnHandleException(exception, "异步任务", HandleFriendlyException);
            e.SetObserved();
        }

        private void HandleFriendlyException(FriendlyException exception)
        {
            if (Dispatcher.Thread != Thread.CurrentThread)
            {
                Dispatcher.Invoke(() => this.ShowError(exception.Message));
            }
            else
            {
                this.ShowError(exception.Message);
            }
        }
    }
}
